package zarzadcyZdarzen;
import java.util.HashMap;


import gui.*;
import gameManager.*;

/**
 * Klasa parsująca i wykonująca komendy przychodzące od serwera, posiada
 * referencje na okno główne i TableManager - bo komendy odnosić się mogą do głównego okna
 * (chat, stoły), jak i poszczególnych gier.
 * 
 * @author Konrad Sobczak
 * @author Kamil Nowak
 *
 */

public class CommandExecutor {

	private HashMap<String,CommandType> string2type = new HashMap<String,CommandType>();
	private TableManager tableManager;
	private MainWindow mainWindow;
	
	public CommandExecutor(MainWindow mw, TableManager tm){
		this.mainWindow = mw;
		this.tableManager = tm;
		init();
	}
	 
	/**
	 * Inicjuje mapę haszującą, aby łatwo zorientować się w typie komendy
	 * jaką przyszło parsować i wykonywać
	 *
	 */
	private void init(){
		string2type.put("HELLO",CommandType.HELLO);
		string2type.put("LOGIN",CommandType.LOGIN);
		string2type.put("OK",CommandType.OK);
		string2type.put("LOGINOK",CommandType.LOGINOK);
		string2type.put("LOGINERR",CommandType.LOGINERR);
		string2type.put("TABLES",CommandType.TABLES);
		string2type.put("GETTABLES",CommandType.GETTABLES);
		string2type.put("SMSG",CommandType.SMSG);
		string2type.put("MSG",CommandType.MSG);
		string2type.put("CREATE",CommandType.CREATE);
		string2type.put("CREATEOK",CommandType.CREATEOK);
		string2type.put("CREATEERR",CommandType.CREATEERR);
		string2type.put("JOIN",CommandType.JOIN);
		string2type.put("JOINOK",CommandType.JOINOK);
		string2type.put("JOINERR",CommandType.JOINERR);
		string2type.put("LEAVETABLE",CommandType.LEAVETABLE);
		string2type.put("ENDGAME",CommandType.ENDGAME);
		string2type.put("MOVE",CommandType.MOVE);
		string2type.put("MOVEOK",CommandType.MOVEOK);
		string2type.put("MOVEERR",CommandType.MOVEERR);
		string2type.put("FINISHGAME",CommandType.FINISHGAME);
		string2type.put("FINISHGAMEOK",CommandType.FINISHGAMEOK);
		string2type.put("TIMEOUT",CommandType.TIMEOUT);
		string2type.put("PROMO",CommandType.PROMO);
	}
	
	/**
	 * Zwraca wartość enum komnendy jeśli komenda o takim stringu występuje, null w przeciwnym
	 * przypadku
	 * @param commandtype - String odpowiadający komendzie
	 * @return zwraca null jeśli komenda nie wysępuje, jej symbol enum jeśli występuje
	 */
	private CommandType getCommandType(String commandtype){
		if(string2type.containsKey(commandtype))
			return string2type.get(commandtype);
		else
			return null;
	}
	
	/**
	 * 
	 * @return zwraca referencje na MainWindow przypisaną w konstruktorze
	 */
	public MainWindow get_MainWindow(){
		return this.mainWindow;
	}
	
	/**
	 * Parsuje i wykonuje komendy w przypadku prawidłowego ich rozpoznania.
	 * @param command - String odpowiadający komendzie wraz z parametrami, opis 
	 * protokołu znajduje się w papierowej częsci dokumentacji, w rozdziale serwera.
	 */
	public void parse_and_execute(String command){
		String[] temp = command.split("\\|");
		CommandType t=getCommandType(temp[0]);
		if(t!=null){
			switch(t){
				case MSG:
					if(Integer.parseInt(temp[1])==0)
						mainWindow.dodajWypowiedzDoChata(temp[3],temp[4]);
					else{
						tableManager.dodajChatMsg(Integer.parseInt(temp[1]),temp[3],temp[4]);
					}
					break;
				case CREATEOK:
					tableManager.zaloz_stol(Integer.parseInt(temp[1]),false);
					break;
				case CREATEERR:
					mainWindow.blad_zakladania_stolu();
					break;
				case TABLES:
					mainWindow.czysc_liste_stolow();
					if(temp.length>1){			
						for(int i=1;i<temp.length-4;i+=5){
							if(Integer.parseInt(temp[i+1])!=mainWindow.get_id_user() && temp[i+4].compareTo("F")==0)
								mainWindow.dodaj_stol(temp[i] + "/" + temp[i+2],Integer.parseInt(temp[i+3]));
						}
					}
					break;
				case JOINOK:
					tableManager.zaloz_stol(Integer.parseInt(temp[1]),true); 
					break;
				case JOINERR:
					mainWindow.blad_joinowania_stolu();
					break;
				case JOIN:
					tableManager.rozpocznij_gre(Integer.parseInt(temp[1]),temp[3]);
					break;
				case ENDGAME:
					tableManager.koniec_gry(Integer.parseInt(temp[1]),Integer.parseInt(temp[2]));
					break;
				case MOVE:
					tableManager.dokonaj_ruchu(Integer.parseInt(temp[1]),Integer.parseInt(temp[4]),Integer.parseInt(temp[5]),Integer.parseInt(temp[6]),Integer.parseInt(temp[7]));
					break;
				case FINISHGAMEOK:
					tableManager.finish_game(Integer.parseInt(temp[1]));
					break;
				case FINISHGAME:
					tableManager.finish_game(Integer.parseInt(temp[1]));
					break;
				case PROMO:
					tableManager.dokonaj_promo(Integer.parseInt(temp[1]),Integer.parseInt(temp[4]),Integer.parseInt(temp[5]),Integer.parseInt(temp[6]),Integer.parseInt(temp[7]),Integer.parseInt(temp[8]));
					break;
			}
		}
		
	}
	
	
}
